package com.suray.wcs.service.plc;

import com.suray.basic.wcs.plc.pojo.oper.lifter.ForkLifterOper;
import com.suray.basic.wcs.plc.utils.LifterTask;
import com.suray.basic.wcs.plc.utils.LifterTaskProcess;
import com.suray.basic.wcs.plc.utils.LifterTaskType;

import java.util.*;

public class LifterTaskContainer {
    private Map<LifterTaskProcess, List<LifterTask>> tasks;
    private int wcsTaskId;
    private int taskCmdNo;
    private String series;
    private LifterTaskProcess process;
    private ForkLifterOper lifterOper;
    private int lastSegment;

    public void init() {
        tasks.clear();
        process = LifterTaskProcess.INIT;
        wcsTaskId = 0;
        lastSegment = 0;
    }

    public LifterTaskContainer(String series, ForkLifterOper lifterOper) {
        this.series = series;
        this.taskCmdNo = LifterConfigParam.LIFTER_INIT_TASK_CMD_NO;
        tasks = new LinkedHashMap<>();
        process = LifterTaskProcess.INIT;
        this.wcsTaskId = 0;
        this.lastSegment = 0;
        this.lifterOper = lifterOper;
    }

    public int getSegment() {
        generalTaskCmdNo();

//        if (process == LifterTaskProcess.INIT) {
            Iterator<LifterTaskProcess> iterator = tasks.keySet().iterator();
            if (iterator.hasNext()) {
                process = tasks.keySet().iterator().next();
            }
//        }

        lastSegment = tasks.get(process).size() + lastSegment;
        return lastSegment;
    }

    public LifterTaskProcess nextSegment() {
        Iterator<LifterTaskProcess> iterator = tasks.keySet().iterator();
        if (iterator.hasNext()) {
            process = tasks.keySet().iterator().next();
        }

        return process;
    }

    public boolean isSegmentEnd(int finishCmd, int taskId) {
        if (wcsTaskId != taskId) {
            return false;
        }

        if (taskCmdNo == finishCmd) {
            tasks.remove(process);
            return true;
        }

        return false;
    }

    public LifterTaskProcess getProcess() {
        return process;
    }

    public int getCmdNo() {
        return taskCmdNo;
    }

    public boolean isTaskEnd(int taskId) {
        if (wcsTaskId != taskId) {
            return false;
        }

        return tasks.size() == 0;
    }

    /**
     * 生成任务
     * @param wcsTaskId
     * @param taskType
     * @param start
     * @param end
     * @return
     */
    public synchronized LifterTask generalTask(Integer wcsTaskId, LifterTaskType taskType, int start, int end,
                                               LifterTaskProcess process) {
        if (!lifterOper.isReady()) {
            throw new RuntimeException("提升机当前状态不能执行任务");
        }

        if (taskType == LifterTaskType.LIFTER_TASK && lifterOper.isHaveShuttle()) {
            //如果四向车在提升机内，则不能生成1层两向车层的任务
            if (lifterOper.getLifterLocationInfoByLifterDis(end).layer == 101) {
                throw new RuntimeException("提升机内有四向车，提升机不能去两向车层");
            }
        }

        if (this.wcsTaskId != 0 && this.wcsTaskId != wcsTaskId) {
            throw new RuntimeException("当前已有任务，不能接收新任务:" + wcsTaskId);
        }

        this.wcsTaskId = wcsTaskId;

        LifterTask task = new LifterTask(wcsTaskId, taskType, start, end);
        if (tasks.containsKey(process)) {
            tasks.get(process).add(task);
        } else {
            List<LifterTask> lifterTasks = new ArrayList<>();
            lifterTasks.add(task);
            tasks.put(process, lifterTasks);
        }
        return task;
    }

    /**
     * 任务完成
     * @param process
     */
    public void taskEnd(LifterTaskProcess process) {
        tasks.remove(process);
    }

    private synchronized int generalTaskCmdNo() {
        if (taskCmdNo < LifterConfigParam.LIFTER_INIT_TASK_CMD_NO) {
            throw new RuntimeException(series + "任务Id异常:" + taskCmdNo);
        }

        taskCmdNo++;

        if (taskCmdNo > LifterConfigParam.LIFTER_MAX_TASK_CMD_NO) {
            taskCmdNo = LifterConfigParam.LIFTER_INIT_TASK_CMD_NO;
        }

        return taskCmdNo;
    }

    /**
     * 获取所有任务动作
     * @return
     */
    public List<LifterTask> getAllTasks() {
        List<LifterTask> lifterTasks = new ArrayList<>();

        tasks.values().forEach(lifterTaskList -> {
            lifterTasks.addAll(lifterTaskList);
        });
        return lifterTasks;
    }

    public void checkTaskId(int taskId) {
        if (wcsTaskId != taskId) {
            throw new RuntimeException("提升机任务id不一致, 当前任务id：" + wcsTaskId + ", 检测任务id：" + taskId);
        }
    }

    public LifterTask getFirstTask() {
        try {
            if (tasks.size() == 0) {
                return null;
            }

            return tasks.values().iterator().next().get(0);
        } catch (Exception e) {
            return null;
        }
    }
}
